﻿#include "configure.h"
#include <memory>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <errno.h>
#include <unistd.h>
 
#include <netdb.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>


configure configure::m_handler;

int configure::load(const std::string& filename)
{
    FILE* pfile = fopen(filename.c_str(), "r");
    if (nullptr == pfile) {
        return -1;
    }
    int readlen = 1024 * 1024;

    std::shared_ptr<char>  bufPtr = std::shared_ptr<char>(
        new char[readlen], [](char* p) {if (p) delete[] p; }
    );

    memset(bufPtr.get(), 0, readlen);
    int rlen = fread(bufPtr.get(), 1, readlen, pfile);
    if (rlen == readlen) {
        fclose(pfile); return -1;
    }
    fclose(pfile);

    bool bret = aigc::JsonHelper::JsonToObject(m_config, bufPtr.get(), {}, NULL);
    if (!bret) {
        return -1;
    }
    //判断是否需要协商秘钥
    for(auto &item:m_config.virtuals){
        if(item.encrypt == 1){
            m_config.m_encrypt = 1;
            break;
        }
    }
    //printf("get config ok");
    //初始化配置文件数据
    char tempmac[32];
    char tempip[64];
    for(auto &item:m_config.virtuals){
        if(0 != getmac(tempmac,item.virtual_name1.c_str())){
            return -2;
        }
        item.virtual_mac1 = tempmac;
        if(0 != getip(tempip,item.virtual_name1.c_str())){
            return -3;
        }
        item.virtual_ip = tempip;
        //printf("addr:%s\n", item.virtual_ip.c_str());//打印网卡对应的ip地址
        if(0 != getmac(tempmac,item.virtual_name2.c_str())){
            return -4;
        }
        item.virtual_mac2 = tempmac;
    }
    if(0 != getmac(tempmac,m_config.physical_name.c_str())){
        return -4;
    }
    m_config.physical_mac = tempmac;

    for(auto &item:m_config.virtuals){
        printf("vir_mac1: %s\n",item.virtual_mac1.c_str());
        printf("vir_mac2: %s\n",item.virtual_mac2.c_str());
    }

    return 0;
}
int configure::getmac(char *mac,const char *name)
{
    //内部函数，调用者保证了mac的空间
    struct ifreq ifreq;
    int   sock;
    //printf("name:%s\n",name);
    if((sock=socket(AF_INET,SOCK_STREAM,0)) <0)
    {
        perror( "socket ");
        return   2;
    }
    strcpy(ifreq.ifr_name, name);
    if(ioctl(sock,SIOCGIFHWADDR,&ifreq) <0)
    {
        perror( "ioctl ");
        return   3;
    }
    sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
            (unsigned char)ifreq.ifr_hwaddr.sa_data[0],
            (unsigned char)ifreq.ifr_hwaddr.sa_data[1],
            (unsigned char)ifreq.ifr_hwaddr.sa_data[2],
            (unsigned char)ifreq.ifr_hwaddr.sa_data[3],
            (unsigned char)ifreq.ifr_hwaddr.sa_data[4],
            (unsigned char)ifreq.ifr_hwaddr.sa_data[5]);
    return 0;
}

int configure::getip(char *addr,const char *name)
{
    struct ifreq temp_ifreq;
	struct sockaddr_in *myaddr;
	int fd = 0;
	unsigned int ipvalue,maskvalue;
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("Build socket failed.\n");
        return -1;
    }
    strcpy(temp_ifreq.ifr_name, name);//指定网卡名称
    //addr
    if (ioctl(fd, SIOCGIFADDR, &temp_ifreq) >= 0)
    {
        char tempaddr[64] = {0};
        myaddr = (struct sockaddr_in *)&(temp_ifreq.ifr_addr);
        inet_ntop(AF_INET, &myaddr->sin_addr, addr, 64);
        ipvalue = myaddr->sin_addr.s_addr;
        //printf("addr:%s\n", addr);//打印网卡对应的ip地址
    }
    else
    {
    	printf("utl_ifconfig_build_attr SIOCGIFADDR failed--[%d][%s]\n", errno, strerror(errno));
    }
    return 0;
}
